﻿using System.Drawing;
using System.IO;
using System.Text;

namespace GMapNET
{
   internal class Cache
   {
      string cache;
      string tileCache;
      string routeCache;
      string geoCache;
      string placemarkCache;

      public string CacheLocation
      {
         get
         {
            return cache;
         }
         set
         {
            cache = value;
            tileCache = cache + "TileCache" + Path.DirectorySeparatorChar;
            routeCache = cache + "RouteCache" + Path.DirectorySeparatorChar;
            geoCache = cache + "GeocoderCache" + Path.DirectorySeparatorChar;
            placemarkCache = cache + "PlacemarkCache" + Path.DirectorySeparatorChar;
         }
      }

      private static long DirSize(DirectoryInfo d)
      {
          long Size = 0;
          // Add file sizes.
          FileInfo[] fis = d.GetFiles();
          foreach (FileInfo fi in fis)
          {
              Size += fi.Length;
          }
          // Add subdirectory sizes.
          DirectoryInfo[] dis = d.GetDirectories();
          foreach (DirectoryInfo di in dis)
          {
              Size += DirSize(di); 
          }
          return (Size);
      }

      public void CheckCacheSize()
      {
          if (Directory.Exists(tileCache))
          {                                               
              if (DirSize(new DirectoryInfo(tileCache)) > 104857600) //increased to 100mb v1017
              {
                  Directory.Delete(tileCache, true);
              }
          }
      }

      public void CacheImage(Image tile, GMapType type, Point pos, int zoom, string language)
      {
         try
         {
            using(tile)
            {
               StringBuilder dir = new StringBuilder(tileCache);
               dir.AppendFormat("{0}{1}{2}{3}{4}{5}{6}{7}", zoom, Path.DirectorySeparatorChar, language, Path.DirectorySeparatorChar, pos.X, Path.DirectorySeparatorChar, pos.Y, Path.DirectorySeparatorChar);

               string d = dir.ToString();

               // precrete dir
               if (!Directory.Exists(d))
               {
                   Directory.CreateDirectory(d);
               }
               

               // save
               {
                  dir.AppendFormat("{0}.png", type.ToString());

                  using(FileStream s = File.Open(dir.ToString(), FileMode.Create, FileAccess.Write, FileShare.None))
                  {
                     tile.Save(s, System.Drawing.Imaging.ImageFormat.Png);
                     s.Flush();
                     s.Close();
                  }

                  // remove crap
                  FileInfo f = new FileInfo(dir.ToString());
                  if(f.Length == 0)
                  {
                     File.Delete(dir.ToString());
                  }
               }
            }
         }
         catch
         {
         }
      }

      public Image GetImageFromCache(GMapType type, Point pos, int zoom, string language)
      {
         Image ret = null;
         try
         {
            StringBuilder dir = new StringBuilder(tileCache);
            dir.AppendFormat("{0}{1}{2}{3}{4}{5}{6}{7}", zoom, Path.DirectorySeparatorChar, language, Path.DirectorySeparatorChar, pos.X, Path.DirectorySeparatorChar, pos.Y, Path.DirectorySeparatorChar);
            {
               dir.AppendFormat("{0}.png", type.ToString());
            }

            if(File.Exists(dir.ToString()))
            {
               FileInfo f = new FileInfo(dir.ToString());
               if(f.Length == 0)
               {
                  f.Delete();
               }
               else
               {
                  using(FileStream s = f.Open(FileMode.Open, FileAccess.Read, FileShare.Read))
                  {
                     ret = Image.FromStream(s);
                     s.Close();
                  }
               }
            }
         }
         catch
         {
            ret = null;
         }

         return ret;
      }

      public void CacheGeocoder(string urlEnd, string content)
      {
         try
         {
            // precrete dir
            if(!Directory.Exists(geoCache))
            {
               Directory.CreateDirectory(geoCache);
            }

            StringBuilder file = new StringBuilder(geoCache);
            file.AppendFormat("{0}.geo", urlEnd);

            File.WriteAllText(file.ToString(), content, Encoding.UTF8);
         }
         catch
         {
         }
      }

      public string GetGeocoderFromCache(string urlEnd)
      {
         string ret = null;

         try
         {
            StringBuilder file = new StringBuilder(geoCache);
            file.AppendFormat("{0}.geo", urlEnd);

            if(File.Exists(file.ToString()))
            {
               ret = File.ReadAllText(file.ToString(), Encoding.UTF8);
            }
         }
         catch
         {
            ret = null;
         }

         return ret;
      }

      public void CachePlacemark(string urlEnd, string content)
      {
         try
         {
            // precrete dir
            if(!Directory.Exists(placemarkCache))
            {
               Directory.CreateDirectory(placemarkCache);
            }

            StringBuilder file = new StringBuilder(placemarkCache);
            file.AppendFormat("{0}.plc", urlEnd);

            File.WriteAllText(file.ToString(), content, Encoding.UTF8);
         }
         catch
         {
         }
      }

      public string GetPlacemarkFromCache(string urlEnd)
      {
         string ret = null;

         try
         {
            StringBuilder file = new StringBuilder(placemarkCache);
            file.AppendFormat("{0}.plc", urlEnd);

            if(File.Exists(file.ToString()))
            {
               ret = File.ReadAllText(file.ToString(), Encoding.UTF8);
            }
         }
         catch
         {
            ret = null;
         }

         return ret;
      }

      public void CacheRoute(string urlEnd, string content)
      {
         try
         {
            // precrete dir
            if(!Directory.Exists(routeCache))
            {
               Directory.CreateDirectory(routeCache);
            }

            StringBuilder file = new StringBuilder(routeCache);
            file.AppendFormat("{0}.dragdir", urlEnd);             

            File.WriteAllText(file.ToString(), content, Encoding.UTF8);
         }
         catch
         {
         }
      }

      public string GetRouteFromCache(string urlEnd)
      {
         string ret = null;

         try
         {
            StringBuilder file = new StringBuilder(routeCache);
            file.AppendFormat("{0}.dragdir", urlEnd);

            if(File.Exists(file.ToString()))
            {
               ret = File.ReadAllText(file.ToString(), Encoding.UTF8);
            }
         }
         catch
         {
            ret = null;
         }

         return ret;
      }
   }
}
